package com.yunxin.core.application.seceiver;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yunxin.common.utils.JacksonUtils;
import com.yunxin.core.admin.domain.*;
import com.yunxin.core.admin.service.*;
import com.yunxin.core.application.seceiver.message.*;
import com.yunxin.core.customer.domain.*;
import com.yunxin.core.customer.mapper.CustomerInfoDetailMapper;
import com.yunxin.core.customer.mapper.CustomerInfoMapper;
import com.yunxin.core.customer.mapper.CustomerShipAllocationMapper;
import com.yunxin.core.customer.service.CustomerShipAllocationService;
import com.yunxin.core.customer.service.CustomerTelephonerLogService;
import com.yunxin.core.domain.external.merchant.MerchantExternalService;
import com.yunxin.core.domain.model.order.OrderUserApply;
import com.yunxin.core.domain.model.order.OrderUserApplyAllocationRepository;
import com.yunxin.core.domain.model.order.OrderUserApplyDetail;
import com.yunxin.core.domain.model.team.UserTeamShip;
import com.yunxin.core.infra.persistence.entity.merchant.MerchantUserAccountDO;
import com.yunxin.core.infra.persistence.entity.product.ProductThrowInConfigDOWithBLOBs;
import com.yunxin.core.infra.persistence.entity.product.query.result.ProductPromotionInfoResult;
import com.yunxin.core.infra.persistence.mapper.merchant.MerchantUserAccountExtendMapper;
import com.yunxin.core.infra.persistence.mapper.product.ProductInfoExtendMapper;
import com.yunxin.core.infra.persistence.mapper.product.ProductThrowInConfigMapper;
import com.yunxin.core.infra.persistence.mapper.user.UserTeamShipMapper;
import com.yunxin.core.utils.infra.support.rabbit.RabbitQueue;
import com.yunxin.core.wechat.config.WechatConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author zero°
 * @since 2024-01-02
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RabbitStatisticsReceiver {

    private final MerchantExternalService merchantExternalService;

    private final OrderUserApplyAllocationRepository orderUserApplyAllocationRepository;

    @Autowired
    @Lazy
    private CustomerInfoDetailMapper customerInfoDetailMapper;

    @Autowired
    @Lazy
    private CustomerInfoMapper customerInfoMapper;

    @Autowired
    @Lazy
    private UserTeamShipMapper userTeamShipMapper;

    @Autowired
    @Lazy
    private ProductInfoExtendMapper productInfoExtendMapper;
    @Autowired
    @Lazy
    private ProductThrowInConfigMapper productThrowInConfigMapper;

    @Autowired
    @Lazy
    private CustomerShipAllocationService customerShipAllocationService;

    private final RedisTemplate redisTemplate;

    private final String redisKey = "allocation_salesmanId";

    @Autowired
    @Lazy
    private AdminUserService adminUserService;

    @Autowired
    @Lazy
    private AdminUserMerchantService adminUserMerchantService;
    @Autowired
    @Lazy
    private AdminUserRoleService adminUserRoleService;

    private final PasswordEncoder passwordEncoder;
    @Autowired
    @Lazy
    private AdminTeamService adminTeamService;
    @Autowired
    @Lazy
    private AdminUserTeamShipService adminUserTeamShipService;
    @Autowired
    @Lazy
    private CustomerTelephonerLogService customerTelephonerLogService;

    /**
     * 消息接收 自动确认ack
     *
     * @param message 消息
     */
    @RabbitListener(queues = RabbitQueue.BokeModelQueue.BOKE_DISTRIBUTION_QUEUE)
    public void bokeDistributionProcess(Message message) {
        String msgId = message.getMessageProperties().getMessageId();
        try {
            MDC.put("TRACE_ID", msgId);
            StatisticsMessage statisticsMessage = JacksonUtils.X.parse(message.getBody(), StatisticsMessage.class);
            log.error("MQ监听数据：" + message.getBody());
            if (statisticsMessage.getStatisticsTypeEnum() == StatisticsTypeEnum.BOKE_DISTRIBUTION_CUSTOMER) { //分配客户
                String data = statisticsMessage.getData();
                if (!ObjectUtils.isEmpty(data)) {
                    // 保存分发数据
                    BokeDistributionStatisticsMessage boke = JacksonUtils.X.parse(data, BokeDistributionStatisticsMessage.class);
                    if (!Objects.isNull(boke)) {
                        // 用户订单
                        OrderUserApply userApply = boke.getUserApply();
                        // 用户订单详情
                        OrderUserApplyDetail applyDetail = boke.getOrderUserApplyDetail();
                        // 属性拷贝
                        CustomerInfo info = new CustomerInfo();
                        CustomerInfoDetail infoDetail = new CustomerInfoDetail();
                        // 客户详情数据拷贝
                        copyProperties(userApply, info, boke.getMerchantId(), boke.getProductId(),boke.getAbutmentType());
                        // 生成企微客户编号
                        Date date = new Date();
                        String format = DateUtil.format(date, "yyyyMMdd");
                        String no = format + getNo();
                        info.setCustomerNo(no);
                        BeanUtils.copyProperties(applyDetail, infoDetail);
                        //Long salesmanId = allocationMerchantAccountId(boke.getMerchantId(), "BOKE_BUSINESS");//获取商户业务员id
                        //判断是否开启商户管理员
                        boolean isMerchantAdmin = isBokeUser(boke.getMerchantId(), "BOKE_MERCHANT_ADMIN");
                        if (!isMerchantAdmin){
                            return;
                        }
                        boolean bokeTelephoneFlag=true;
                        if (boke.getAbutmentType()!=4){
                            UserTeamShip bokeTelephone = allocationMerchantAccountId(boke.getMerchantId(), "BOKE_TELEPHONE");//获取商户话务员id
                            if (!ObjectUtils.isEmpty(bokeTelephone) ) {
                                info.setTelephonerId(bokeTelephone.getUserMerchantId().intValue());
                                info.setTelephonerTime(new Date());
                                info.setTeamId(bokeTelephone.getTeamId().intValue());
                                bokeTelephoneFlag=false;
                                //ProductThrowInConfigDOWithBLOBs bs = productThrowInConfigMapper.selectByPrimaryKey(boke.getProductId());

//                            LambdaQueryWrapper<AdminTeam> adminTeamLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                            adminTeamLambdaQueryWrapper.eq(AdminTeam::getMerchantId, boke.getMerchantId());
//                            List<AdminTeam> teams = adminTeamService.list(adminTeamLambdaQueryWrapper);
//                            List<Integer> teamIds = teams.stream().map(i -> i.getId()).toList();
//
//                            //if (bs.getAbutmentType() != 4) {
//                            LambdaQueryWrapper<CustomerShipAllocation> queryWrapper = new LambdaQueryWrapper<>();
//                            queryWrapper.eq(CustomerShipAllocation::getTelephoneId, bokeTelephone.getUserMerchantId())
//                                    .orderByDesc(CustomerShipAllocation::getCreateTime)
//                                    .in(CustomerShipAllocation::getTeamId, teamIds);
//                            List<CustomerShipAllocation> allocations = customerShipAllocationService.list(queryWrapper);
//                            if (CollUtil.isNotEmpty(allocations)) {
//                                Random rand = new Random();
//                                int rundNum = rand.nextInt(allocations.size());
//                                Integer salesmanId = allocations.get(rundNum).getSalesmanId();
//                                info.setSalesmanId(salesmanId);
//                                info.setTeamId(allocations.get(rundNum).getTeamId());
//                            } else {
//                                info.setSalesmanId(-1);
//                                LambdaQueryWrapper<AdminUserTeamShip> teamShipLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                                teamShipLambdaQueryWrapper.eq(AdminUserTeamShip::getUserMerchantId, bokeTelephone.getUserMerchantId())
//                                        .in(AdminUserTeamShip::getTeamId, teamIds);
//                                List<AdminUserTeamShip> teamShipList = adminUserTeamShipService.list(teamShipLambdaQueryWrapper);
//                                Random rand = new Random();
//                                int rundNum = rand.nextInt(teamShipList.size());
//                                info.setTeamId(teamShipList.get(rundNum).getTeamId());
//                            }
                                //}
                            }else {
                                log.error("波克客服数据存储异常商户id:", boke.getMerchantId() + ":该商户没有波克话务员开启接单状态");
                            }
                        }
                        if (bokeTelephoneFlag){
                            //商户池
                            info.setTelephonerId(-1);
                            info.setTeamId(-1);
                        }
                        info.setSalesmanId(-1);

                        try {
                            customerInfoMapper.insert(info);
                            infoDetail.setCustomerInfoId(info.getId());
                            customerInfoDetailMapper.insert(infoDetail);
                            //保存分配日志
                            if (!ObjectUtils.isEmpty(info.getTelephonerId()) && info.getTelephonerId()!=-1){
                                CustomerTelephonerLog customerTelephonerLog=new CustomerTelephonerLog();
                                customerTelephonerLog.setCustomerInfoId(info.getId());
                                customerTelephonerLog.setUserId(info.getTelephonerId().longValue());
                                customerTelephonerLog.setType(1);
                                customerTelephonerLog.setCreateTime(info.getTelephonerTime());
                                customerTelephonerLogService.save(customerTelephonerLog);
                            }

                        } catch (Exception e) {
                            log.info("波克客服数据存储异常,{}", e.getMessage());
                        }
                    }
                }
            } else if (statisticsMessage.getStatisticsTypeEnum() == StatisticsTypeEnum.BOKE_CREATE_MERCHANT_ADMIN) {
                String data = statisticsMessage.getData();
                AddBokeUserCommand bokeUserCommand = JacksonUtils.X.parse(data, AddBokeUserCommand.class);
                if (bokeUserCommand.getType() == 0) {//创建商户管理员
                    long count = adminUserService.count(new LambdaQueryWrapper<AdminUser>().eq(AdminUser::getUsername, bokeUserCommand.getUsername()));
                    if (count > 0) {
                        log.info("创建商户管理员失败,用户名已存在,{}", bokeUserCommand.getId());
                    }
                    long countPhone = adminUserService.count(new LambdaQueryWrapper<AdminUser>().eq(AdminUser::getMobile, bokeUserCommand.getMobile()));
                    if (countPhone > 0) {
                        log.info("创建商户管理员失败,手机号已存在,{}", bokeUserCommand.getId());
                    }
                    AdminUser adminUser = new AdminUser();
                    BeanUtils.copyProperties(bokeUserCommand, adminUser, "id");
                    adminUser.setYdUserId(bokeUserCommand.getId());
                    adminUser.setUserType(2);
                    adminUser.setPassword(passwordEncoder.encode(adminUser.getPassword()));

                    adminUserService.save(adminUser);
                    //保存商户
                    AdminUserMerchant adminUserMerchant = new AdminUserMerchant();
                    adminUserMerchant.setMerchantId(bokeUserCommand.getMerchantId());
                    adminUserMerchant.setUserId(adminUser.getId().longValue());
                    adminUserMerchantService.save(adminUserMerchant);
                    //保存角色
                    AdminUserRole adminUserRole = new AdminUserRole();
                    adminUserRole.setUserId(adminUser.getId().longValue());
                    adminUserRole.setRoleId(13L);
                    adminUserRoleService.save(adminUserRole);
                } else if (bokeUserCommand.getType() == 1) { //修改
                    long count = adminUserService.count(new LambdaQueryWrapper<AdminUser>().eq(AdminUser::getUsername, bokeUserCommand.getUsername())
                            .ne(AdminUser::getYdUserId, bokeUserCommand.getId()));
                    if (count > 0) {
                        log.info("修改商户管理员失败,用户名已存在,{}", bokeUserCommand.getId());
                    }
                    long countPhone = adminUserService.count(new LambdaQueryWrapper<AdminUser>().eq(AdminUser::getMobile, bokeUserCommand.getMobile())
                            .ne(AdminUser::getYdUserId, bokeUserCommand.getId()));
                    if (countPhone > 0) {
                        log.info("修改商户管理员失败,手机号已存在,{}", bokeUserCommand.getId());
                    }
                    LambdaQueryWrapper<AdminUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    userLambdaQueryWrapper.eq(AdminUser::getYdUserId, bokeUserCommand.getId());
                    AdminUser adminUser = adminUserService.getOne(userLambdaQueryWrapper);
                    if (ObjectUtils.isEmpty(adminUser) && bokeUserCommand.getRoleIds().contains(3L)) { //新增
                        adminUser = new AdminUser();
                        BeanUtils.copyProperties(bokeUserCommand, adminUser, "id");
                        adminUser.setYdUserId(bokeUserCommand.getId());
                        adminUser.setUserType(2);
                        adminUser.setPassword(adminUser.getPassword());
                        adminUser.setCreator("腰带系统管理员创建");
                        adminUser.setCreateTime(new Date());
                        adminUserService.save(adminUser);
                        //保存商户
                        AdminUserMerchant adminUserMerchant = new AdminUserMerchant();
                        adminUserMerchant.setMerchantId(bokeUserCommand.getMerchantId());
                        adminUserMerchant.setUserId(adminUser.getId().longValue());
                        adminUserMerchantService.save(adminUserMerchant);
                        //保存角色
                        AdminUserRole adminUserRole = new AdminUserRole();
                        adminUserRole.setUserId(adminUser.getId().longValue());
                        adminUserRole.setRoleId(13L);
                        adminUserRoleService.save(adminUserRole);
                    } else { //修改
                        BeanUtils.copyProperties(bokeUserCommand, adminUser, "id");
                        adminUserService.updateById(adminUser);
                        //修改商户关联
                        LambdaUpdateWrapper<AdminUserMerchant> queryWrapper = new LambdaUpdateWrapper<>();
                        queryWrapper.eq(AdminUserMerchant::getUserId, adminUser.getId())
                                .set(AdminUserMerchant::getMerchantId, bokeUserCommand.getMerchantId());
                        adminUserMerchantService.update(queryWrapper);
                        //修改角色
                        LambdaQueryWrapper<AdminUserRole> roleLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        roleLambdaQueryWrapper.eq(AdminUserRole::getUserId, adminUser.getId())
                                .eq(AdminUserRole::getRoleId, 13);
                        if (!bokeUserCommand.getRoleIds().contains(3L)) {
                            adminUserRoleService.remove(roleLambdaQueryWrapper);
                        } else {
                            AdminUserRole adminUserRole = adminUserRoleService.getOne(roleLambdaQueryWrapper);
                            if (ObjectUtils.isEmpty(adminUserRole)) {
                                adminUserRole = new AdminUserRole();
                                adminUserRole.setUserId(adminUser.getId().longValue());
                                adminUserRole.setRoleId(13L);
                                adminUserRoleService.save(adminUserRole);
                            }
                        }
                    }

                } else if (bokeUserCommand.getType() == 2) { //修改状态
                    LambdaUpdateWrapper<AdminUser> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(AdminUser::getYdUserId, bokeUserCommand.getId())
                            .set(AdminUser::getStatus, bokeUserCommand.getStatus());
                    adminUserService.update(updateWrapper);
                } else if (bokeUserCommand.getType() == 3) { //修改密码
                    LambdaUpdateWrapper<AdminUser> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(AdminUser::getYdUserId, bokeUserCommand.getId())
                            .set(AdminUser::getPassword, passwordEncoder.encode(bokeUserCommand.getPassword()));
                    adminUserService.update(updateWrapper);
                } else if (bokeUserCommand.getType() == -1) { //删除
                    LambdaUpdateWrapper<AdminUser> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(AdminUser::getYdUserId, bokeUserCommand.getId());
                    adminUserService.remove(updateWrapper);
                }
            } else {
                log.info("波克分发客服数据不存在, statisticsTypeEnum={}", statisticsMessage.getStatisticsTypeEnum().name());
            }
        } catch (Exception e) {
            log.error("波克分发客服队列处理异常, msgId={}", msgId, e);
        }
    }
    //根据商户id随机获取话务员或业务员
    public UserTeamShip allocationMerchantAccountId(Long merchantId, String code) {

        List<UserTeamShip> accountIds = merchantExternalService.listAccountIdByMerchantId(merchantId, code);
        if (accountIds.isEmpty()) {
            return null;
        }
        List<UserTeamShip> openUserList = accountIds.stream().filter(i -> i.getReceivingStatus() == 1).toList();
        if (!openUserList.isEmpty()){
            Random rand = new Random();
            int randNum = rand.nextInt(openUserList.size());
            UserTeamShip userTeamShip = openUserList.get(randNum);
            return userTeamShip;
        }
        Optional<UserTeamShip> latestUserTeamShip = accountIds.stream()
                .max(Comparator.comparing(UserTeamShip::getUpdateTime));
        return latestUserTeamShip.get();
    }

    private boolean isBokeUser(Long merchantId, String code){
        List<Integer> bokeUserList = merchantExternalService.isBokeUser(merchantId, code);
        if (bokeUserList.isEmpty()){
            return false;
        }
        return true;
    }




    private void copyProperties(OrderUserApply userApply, CustomerInfo info, Long merchantId, Long productId,Integer abutmentType) {
        ProductPromotionInfoResult infoResult = productInfoExtendMapper.selectByProductId(productId);
        info.setApplyOrderNo(userApply.getApplyOrderNo());
        info.setName(userApply.getUserName());
        info.setPhone(userApply.getUserPhone());
        info.setApplyTime(new Date());
        //info.setSalesmanTime(new Date());
        info.setChannelId(userApply.getChannelId());
        info.setSource(3);
        info.setMerchantId(merchantId);
        info.setProductId(productId);
        info.setAbutmentType(abutmentType);
        if (!ObjectUtils.isEmpty(infoResult)) {
            info.setProductName(infoResult.getProductName());
        }
    }

    private String getNo() {
        LocalDateTime endTime = LocalDateTime.now();
        // 获取今天的日期
        LocalDate today = LocalDate.now();
        // 获取这一天的开始时间（即当天的 00:00:00）
        LocalDateTime starTime = today.atStartOfDay();
        List<CustomerInfo> list = customerInfoMapper.selectList(new LambdaQueryWrapper<CustomerInfo>().between(CustomerInfo::getCreateTime, starTime, endTime).orderByDesc(CustomerInfo::getId));
        int size = list.size() + 1;
        return StringUtils.leftPad(String.valueOf(size), 4, '0');

    }

}
